package com.tjec.project.system.controller;

import com.tjec.common.constant.Constants;
import com.tjec.common.exception.file.InvalidExtensionException;
import com.tjec.common.utils.IdUtils;
import com.tjec.common.utils.SFtpUtil;
import com.tjec.common.utils.StringUtils;
import com.tjec.common.utils.file.FileUploadUtils;
import com.tjec.common.utils.file.MimeTypeUtils;
import com.tjec.common.utils.ftp.FavFTPUtil;
import com.tjec.framework.redis.RedisCache;
import com.tjec.framework.web.domain.AjaxResult;
import com.tjec.project.system.domain.BmsAttachmentChunk;
import com.tjec.project.system.domain.FileInfo;
import com.tjec.project.system.service.ChunkService;
import com.tjec.project.system.service.FileInfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 上传Controller
 *
 * @author liuxu
 * @date 2020-04-13
 */
@Api(value = "大文件上传Controller", tags = {"大文件上传接口"})
@RestController
@RequestMapping("/api/system/uploader")
public class UploadController {
    private static final Logger log = LoggerFactory.getLogger(UploadController.class);

    @Value("${tjec.profile}")
    private String profile;
    @Value("${prop.upload-folder}")
    private String uploadFolder;
    @Value("${prop.upload-folder-new}")
    private String uploadFolderNew;
    @Value("${prop.upload-chunk-folder}")
    private String uploadChunkFolder;
    @Resource
    private FileInfoService fileInfoService;
    @Resource
    private ChunkService chunkService;
    @Autowired
    private SFtpUtil sftp;

    @Value("${sftp.http}")
    private String http;
    @Value("${sftp.uploadId}")
    private String ip;
    
    @Value("${ftp.ip}")
    private String ftpIp;
    @Value("${ftp.username}")
    private String username;
    @Value("${ftp.password}")
    private String password;
    @Value("${ftp.port}")
    private Integer port;
    
    //@Autowired
	//private RedisTemplate<Object, Object> redisTemplate;

    /**
     * 用于上传并存储文件块，需要对文件块名进行编号，再存储在指定路径下
     *
     * @param bmsAttachmentChunk
     * @return
     */
    @ApiOperation("用于上传并存储文件块，需要对文件块名进行编号，再存储在指定路径下")
    @PostMapping("/chunk")
    public String uploadChunk(BmsAttachmentChunk bmsAttachmentChunk) {
        MultipartFile file = bmsAttachmentChunk.getFile();

        String extension = FileUploadUtils.getExtension(file);
        if (FileUploadUtils.isNotAllowedExtension(extension, MimeTypeUtils.DEFAULT_NOT_ALLOWED_EXTENSION)) {
            return "文件上传失败,该文件格式不允许上传";
        }
        String filename = file.getOriginalFilename();
        /*if (Arrays.stream(MimeTypeUtils.SPECIAL_CHARACTERS).anyMatch(a -> filename.indexOf(a) != -1)) {
            return "文件名存在非法字符,不允许上传";
        }*/
        log.debug("file originName: {}, chunkNumber: {}", file.getOriginalFilename(), bmsAttachmentChunk.getChunkNumber());

        try {
        	
        	
            /*byte[] bytes = file.getBytes();
            Path path = Paths.get(FileUtils.generatePath(profile + uploadChunkFolder, bmsAttachmentChunk));
            //文件写入指定路径
            Files.write(path, bytes);*/

            //String uploadFile = FtpUtils.uploadFile("filePath", file.getBytes(), UUID.randomUUID().toString().replaceAll("-", "") + ".jpg");
            //FtpUtils.listFileNames("120.25.219.66", 22, "root", "H3password", "/home/tjec/uploadPath/liuxu",file);
            log.debug("uploadFolder:{}", uploadFolder);
            //sftp.connectServer();
            InputStream in = file.getInputStream();
            //FavFTPUtil favFTPUtil = new FavFTPUtil();
            FavFTPUtil.uploadFile(ftpIp, port, username, password, profile + uploadChunkFolder + "/" + bmsAttachmentChunk.getIdentifier() + "/", bmsAttachmentChunk.getFilename() + "-" + bmsAttachmentChunk.getChunkNumber(), in);
            //sftpHelper.upload(profile + uploadChunkFolder + "/" + bmsAttachmentChunk.getIdentifier() + "/", bmsAttachmentChunk.getFilename() + "-" + bmsAttachmentChunk.getChunkNumber(), in);
            //sftp.put(in, profile + uploadChunkFolder + "/" + bmsAttachmentChunk.getIdentifier() + "/", bmsAttachmentChunk.getFilename() + "-" + bmsAttachmentChunk.getChunkNumber());
            chunkService.saveChunk(bmsAttachmentChunk);
            log.debug("文件 {} 写入成功, uuid:{}", bmsAttachmentChunk.getFilename(), bmsAttachmentChunk.getIdentifier());

            return "文件上传成功";
        } catch (IOException e) {
            e.printStackTrace();
            return "后端异常...";
        } catch (Exception e) {
            e.printStackTrace();
            return "后端异常...";
        }
    }

    @ApiOperation("检查文件块是否上传过")
    @GetMapping("/chunk")
    public Object checkChunk(BmsAttachmentChunk bmsAttachmentChunk, HttpServletResponse response) {
        if (chunkService.checkChunk(bmsAttachmentChunk)) {
            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
        }

        return bmsAttachmentChunk;
    }
    
    @ApiOperation("合并文件块")
    @PostMapping("/mergeFile")
    public void mergeFile(FileInfo fileInfo) throws Exception {
    	
    	test(fileInfo);
    }
    
    public synchronized void test(FileInfo fileInfo) throws Exception {
    	
        String filename = fileInfo.getFilename();
        String splitStr = "";
        String path = fileInfo.getPath();
        if(StringUtils.isNotBlank(path)){
            splitStr = "/" + path;
        }
        String file = profile + uploadFolderNew + splitStr +  "/" + fileInfo.getIdentifier() + "/";
        String folder = profile + uploadChunkFolder + "/" + fileInfo.getIdentifier() + "/";
        sftp.connectServer();
        
        sftp.merge(file, folder, filename);
    }

   /* @ApiOperation("合并文件块")
    @PostMapping("/mergeFile")
    public String mergeFile(FileInfo fileInfo) throws Exception {
    	
    	return test(fileInfo);
    }
    
    public synchronized String test(FileInfo fileInfo) throws Exception {
    	
        String filename = fileInfo.getFilename();
        String splitStr = "";
        String path = fileInfo.getPath();
        if(StringUtils.isNotBlank(path)){
            splitStr = "/" + path;
        }
        String file = profile + uploadFolderNew + splitStr +  "/" + fileInfo.getIdentifier() + "/";
        String folder = profile + uploadChunkFolder + "/" + fileInfo.getIdentifier() + "/";
        sftp.connectServer();
        
        sftp.merge(file, folder, filename);
        //FavFTPUtil.merge("10.66.37.181", 21, "root", "Tjec33626713", file, folder, filename);
        fileInfo.setLocation("/"+uploadFolderNew + splitStr + "/" + fileInfo.getIdentifier() + "/" + filename);
        String guid = fileInfoService.addFileInfo(fileInfo);
        return guid;

        /*SFtpUtil sftp = new SFtpUtil();
        sftp.connectServer();
        InputStream sbs  = sftp.download("/home/tjec/uploadPath/liuxu/chunk/1592969448295/", "任务管理清单模板文件.xlsx-1");
        sftp.put(sbs, "/home/tjec/uploadPath/liuxu/files/1592969448295/", "任务管理清单模板文件.xlsx");
        return "接口成功";
    
    }*/

    @ApiOperation("先存储数据库")
    @PostMapping("/getMergeFileId")
    public String getFileGuid(FileInfo fileInfo) {
    	String filename = fileInfo.getFilename();
    	String splitStr = "";
        String path = fileInfo.getPath();
	     if(StringUtils.isNotBlank(path)){
	         splitStr = "/" + path;
	     }
    	fileInfo.setLocation("/"+uploadFolderNew + splitStr + "/" + fileInfo.getIdentifier() + "/" + filename);
    	String guid = fileInfoService.addFileInfo(fileInfo);
    	return guid;
    }

    @ApiOperation("删除文件")
    @DeleteMapping("deleteFile")
    public String deleteFile(FileInfo fileInfo) {
        if (StringUtils.isBlank(fileInfo.getId())) {
            return "参数不合法";
        }
        fileInfoService.delFileInfo(fileInfo);

        return "删除成功";
    }

    /**
     * 图片上传
     *
     * @param files
     * @return
     * @throws IOException
     */
    @ApiOperation("上传多个图片")
    @ApiImplicitParam(name = "images", value = "图片文件", required = true, dataType = "Array")
//    @Log(title = "上传多个图片", businessType = BusinessType.INSERT)
    @PostMapping("/images")
    public AjaxResult image(@RequestParam("images") List<MultipartFile> files,@RequestParam("path") String path) throws Exception {
        List<Map<String, Object>> fileGuids = new ArrayList<>();
        if (!files.isEmpty() && files.size() > 0) {
            String splitStr = "";
            if(StringUtils.isNotBlank(path)){
                splitStr = "/" + path;
            }
            for (MultipartFile file : files) {
                String fileName = IdUtils.simpleUUID() + "." + FileUploadUtils.getExtension(file);
                FileInfo fileInfo = new FileInfo();
                fileInfo.setFilename(file.getOriginalFilename());
                fileInfo.setTotalSize(file.getSize());
                fileInfo.setType(file.getContentType());
                //文件大小校验
                FileUploadUtils.assertAllowed(file, MimeTypeUtils.IMAGE_EXTENSION);
                String url = uploadFolder + "/images" + splitStr + "/";
//                String completeUrl = profile + url;
                fileInfo.setLocation(url +fileName );
                //sftp.connectServer();
                InputStream in = file.getInputStream();
                //sftp.put(in, profile + url, fileName);
                FavFTPUtil.uploadFiles(ftpIp, port, username, password, profile, url, fileName, in);
//                FileUploadUtils.uploadCompleteDir(completeUrl, file, MimeTypeUtils.IMAGE_EXTENSION);
                String fileGuid = fileInfoService.addFileInfo(fileInfo);
                Map<String, Object> map = new HashMap();
                map.put("fileId", fileGuid);
                map.put("fileUrl", http + ip + Constants.RESOURCE_PREFIX + url + fileName);
                map.put("fileName", file.getOriginalFilename());
                fileGuids.add(map);
            }
            return AjaxResult.success(fileGuids);
        }
        return AjaxResult.error("上传图片异常");
    }
}
